package com.ruoyi.framework.config;


import java.io.IOException;
import java.text.DecimalFormat;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.ruoyi.project.system.sending.service.ITbPlcSendingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ruoyi.project.system.sending.domain.TbPlcSending;
import com.ruoyi.project.system.sending.mapper.TbPlcSendingMapper;


@ServerEndpoint(value = "/websocket")
@Component
public class MyWebSocket {

    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private static Session session;


    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);     //加入set中
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
        System.out.println("有一连接关闭！当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) throws IOException, InterruptedException {
        int index = message.indexOf("=");
        String flag = message.substring(0,index);
        String afterInex = message.substring(index+1);//标记后的字符串
        if ("auto".equals(flag)){//全自动数据
            byte[] sendPlcs = changeToPlcNumber(afterInex);
            //向plc发送全自动数据
			GetSocketInfoThread.socket.getOutputStream().write(sendPlcs);
            System.out.println("发送完成！！！");
        }
        if ("left".equals(flag) || "right".equals(flag)){//半自动数据 左侧
            String[] strings = afterInex.split(",");
            int angle = Integer.valueOf(strings[0]);//角度
            int result = Integer.valueOf(strings[1]);//是否扫描完成
            int x = 190000 - (int)(Float.valueOf(strings[2])*100);//以柱子为原点
            int y = -(2500 - (int)(Float.valueOf(strings[3])*100));
            int z = (int)(Float.valueOf(strings[4])*100);
            byte[] sendPlcs = new byte[80];
            sendPlcs[0] = (byte)0;
            sendPlcs[1] = (byte)angle;//起始角度
            sendPlcs[2] = (byte)0;
            sendPlcs[3] = (byte)result;//扫描信息

            byte[] xbytes = changeNumber(Math.abs(x));
            byte[] ybytes = changeNumber(Math.abs(y));
            byte[] zbytes = changeNumber(Math.abs(z));
            if("left".equals(flag)) {
            	for (int i = 4;i<28;i++){
                    if (i<8){
                        sendPlcs[i] = xbytes[i-4];
                    }
                    if (i >= 8 && i< 12){
                        sendPlcs[i] = ybytes[i-8];
                    }
                    if (i>= 12 && i<16){
                        sendPlcs[i] = zbytes[i-12];
                    }
                }
            }
            
            if("right".equals(flag)) {
            	for (int i = 16;i < 28;i++){
                    if (i < 20){
                        sendPlcs[i] = xbytes[i-16];
                    }
                    if (i >= 20 && i < 24){
                        sendPlcs[i] = ybytes[i-20];
                    }
                    if (i>= 24 && i < 28){
                        sendPlcs[i] = zbytes[i-24];
                    }
                }
            }
            sendPlcs[79] =1;//代表新数据
            //向plc发送半自动数据
            GetSocketInfoThread.socket.getOutputStream().write(sendPlcs);
        }
    }

     /**
      * 群发自定义消息
      * */
    public static void sendInfo(String message) throws IOException {
        for (MyWebSocket item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
        //this.session.getAsyncRemote().sendText(message);
    }
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    /**
     * 转换成可以发送到plc的数据
     * @param number
     * @return
     */
    public static  byte[] changeNumber(int number){
        byte[] b = new byte[4];
        String hex = Integer.toHexString(number);
        StringBuffer stringBuffer = new StringBuffer(hex);

        while (hex.length() <8){
            hex = new StringBuffer("0").append(hex).toString();
        }
        System.out.println(hex);
        for (int i =0;i<hex.length();){
            String newHex = hex.substring(i,i+2);

            b[i/2] = (byte)Integer.parseInt(newHex,16);
            i+=2;
        }
        return  b;
    }
    
    
    

    /**
     * 发送400个坐标数据
     * @param numberStr 字符串400个0 ,1 点
     * @return
     *
     */
    public byte[] changeToPlcNumber(String numberStr){
        String no1 = numberStr.substring(0,1);//云台角度信息
        String no2 = numberStr.substring(1,2);//扫描是否完成
        String no3 = numberStr.substring(2);//400格子 高度标记
        int len = no3.length();

        byte[] sendBytes = new byte[80];
        sendBytes[0] = 0;//云台角度
        sendBytes[1] = Byte.parseByte(no1);//云台角度
        System.out.println("云台角度"+no1);
        sendBytes[2] = 0;//扫描信息
        sendBytes[3] = Byte.parseByte(no2);//扫描信息
        System.out.println("扫描信息"+no2);
        //左右坐标系 x y z 值
        for (int i = 4 ;i < 28 ;i++) {
            sendBytes[i] = 0;
        }
        
        if (len > 0){
            if (len%8 == 0){
                for (int i = 0;i<400;){
                    String string = numberStr.substring(i,i+8);
                    int n = Integer.valueOf(string,2);//将二进制转10进制
                    sendBytes[i/8 + 28] = (byte)n;
                    i=i+8;
                }
            }
        }
        sendBytes[79] =1;//代表新数据
        return sendBytes;
    }

    /**
     * 8未前补零
     * @param number
     * @return
     */
    public static String beforeFillZero(String number){
        DecimalFormat g = new DecimalFormat("00000000");
        String newNumber = g.format(Integer.valueOf(number));
        return  newNumber;
    }
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        MyWebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        MyWebSocket.onlineCount--;
    }


}
